package bavaria.hightec.banking;

import java.io.IOException;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Vector;

import bavaria.hightec.comparators.CompAmount;
import bavaria.hightec.comparators.CompDate;
import bavaria.hightec.comparators.CompMatter;
import bavaria.hightec.exceptions.OverCheckException;
import bavaria.hightec.formatter.StatementFormatter;
import bavaria.hightec.time.TimeEmitter;

public abstract class Account{
	
	private int accountNumber;
	private Money balance;
	private static Currency currency;
	private String accountHolder;
	
	private List <Accounting> list;
	private Map<String, Comparator<Accounting>> sortSelection;
	
//	private List<Accounting> list;
	private Date creation;
	private static ResourceBundle cur;
	
	
	public Account(Date creation,int accountNumber,String accountHolder){
		cur = BankImpl.getLocale();
		String value = cur.getString("CURRENCY");
		currency = Currency.valueOf(value);
		
		this.creation=creation;
		this.accountNumber=accountNumber;
		this.accountHolder=accountHolder;
		this.list=new Vector<Accounting>();
		this.balance = new Money(0,currency);
		sortSelection=new Hashtable<String, Comparator<Accounting>>();
		sortSelection.put("Matter", new CompMatter());
		sortSelection.put("Amount", new CompAmount());
		sortSelection.put("Date", new CompDate());	}
	
	public int getAccountNumber(){
		return accountNumber;
	}
	
	public Date getCreationDate(){
		return creation;
	}
	
	public long getBalance(){
		return balance.getAmount();
	}
	
	public static Currency getCurrency(){
		return currency;
	}
	
	public String getAccountHolder(){
		return accountHolder;
	}
	
	
	
	
	private void update(Money amount,String matter)throws OverCheckException{
			Date accounting = TimeEmitter.getInstance().getCalendar().getTime();
			Accounting accounting2 = new Accounting(accounting,amount,matter);
			balance.addition(amount.getAmount(), amount.getCurrency());
			list.add(accounting2);
		
	}
	
	
	
	public void creditEntry(Money betrag,String matter) throws OverCheckException{
	
			update(betrag,matter);
			
	}
	
	public void debitEntry(Money amount,String matter) throws OverCheckException{
		long geld=-amount.getAmount();
		Money money = new Money(geld,amount.getCurrency());

		update(money,matter);
		
	}
	
	/**Verzinsungsmethode. Abstrakt 
	 * @throws OverCheckException **/
	
	public abstract void chargeInterest() throws OverCheckException;
	
	public String toString(){
		String string = "Kontoinhaber: " + accountHolder + ". Kontonummer: " + accountNumber + " Kontostand: " + getBalance();
		return string;
	}
		
	public String statement(String mimeType) throws IOException{
		StatementFormatter state= new Statement().getStatement(mimeType);
		state.addAccount(this);
		int position = 0;
		for(Iterator<Accounting> iter = list.iterator(); iter.hasNext();){
			list.get(position++).getData();
			state.addTransaction(iter.next());
		}
		return state.getStatement();
	}

	public void sort(String type){
		Collections.sort(list,sortSelection.get(type));
		
	}
	
	

	
}
